<template>
  <view class="card" :class="cardClass" :style="cardStyle" @click="handleClick">
    <!-- 卡片头部 -->
    <view v-if="showHeader" class="card__header" :style="headerStyle">
      <!-- 左侧标题区域 -->
      <view class="card__header-left">
        <!-- 头部图标 -->
        <view v-if="headerIcon" class="card__header-icon">
          <text class="icon">{{ headerIcon }}</text>
        </view>

        <!-- 头部标题 -->
        <view class="card__header-title">
          <text v-if="title" class="title-text">{{ title }}</text>
          <text v-if="subtitle" class="subtitle-text">{{ subtitle }}</text>
        </view>
      </view>

      <!-- 右侧操作区域 -->
      <view class="card__header-right">
        <!-- 额外信息 -->
        <view v-if="extra" class="card__header-extra">
          <text class="extra-text">{{ extra }}</text>
        </view>

        <!-- 操作按钮 -->
        <view v-if="$slots.actions" class="card__header-actions">
          <slot name="actions"></slot>
        </view>

        <!-- 箭头图标 -->
        <view v-if="showArrow" class="card__header-arrow">
          <text class="arrow-icon">›</text>
        </view>
      </view>
    </view>

    <!-- 卡片封面 -->
    <view v-if="cover" class="card__cover">
      <image
        class="cover-image"
        :src="cover"
        :mode="coverMode"
        @load="handleCoverLoad"
        @error="handleCoverError"
      />
      <!-- 封面内容 -->
      <view v-if="$slots.coverContent" class="cover-content">
        <slot name="coverContent"></slot>
      </view>
    </view>

    <!-- 卡片内容 -->
    <view class="card__body" :style="bodyStyle">
      <slot>
        <!-- 默认内容 -->
        <text v-if="content" class="content-text">{{ content }}</text>
      </slot>
    </view>

    <!-- 卡片底部 -->
    <view v-if="showFooter" class="card__footer" :style="footerStyle">
      <!-- 底部左侧内容 -->
      <view class="card__footer-left">
        <slot name="footerLeft"></slot>
      </view>

      <!-- 底部右侧内容 -->
      <view class="card__footer-right">
        <slot name="footerRight"></slot>
      </view>

      <!-- 底部中间内容 -->
      <view v-if="$slots.footer" class="card__footer-center">
        <slot name="footer"></slot>
      </view>
    </view>

    <!-- 卡片标签 -->
    <view v-if="tags && tags.length > 0" class="card__tags">
      <view
        v-for="(tag, index) in tags"
        :key="index"
        class="tag"
        :class="getTagClass(tag)"
        :style="getTagStyle(tag)"
      >
        <text class="tag-text">{{ tag.text }}</text>
      </view>
    </view>

    <!-- 加载状态 -->
    <view v-if="loading" class="card__loading">
      <view class="loading-spinner"></view>
      <text class="loading-text">{{ loadingText }}</text>
    </view>

    <!-- 空状态 -->
    <view v-if="empty" class="card__empty">
      <view class="empty-icon">{{ emptyIcon }}</view>
      <text class="empty-text">{{ emptyText }}</text>
      <text v-if="emptyDescription" class="empty-description">{{ emptyDescription }}</text>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

// 标签接口
interface Tag {
  text: string
  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
  color?: string
  backgroundColor?: string
}

// Props
interface Props {
  title?: string
  subtitle?: string
  content?: string
  extra?: string
  cover?: string
  coverMode?: 'scaleToFill' | 'aspectFit' | 'aspectFill' | 'widthFix' | 'heightFix'
  headerIcon?: string
  tags?: Tag[]
  loading?: boolean
  loadingText?: string
  empty?: boolean
  emptyIcon?: string
  emptyText?: string
  emptyDescription?: string
  showHeader?: boolean
  showFooter?: boolean
  showArrow?: boolean
  clickable?: boolean
  shadow?: 'never' | 'hover' | 'always'
  bordered?: boolean
  padding?: string
  margin?: string
  backgroundColor?: string
  borderRadius?: string
  headerBackgroundColor?: string
  bodyBackgroundColor?: string
  footerBackgroundColor?: string
  customClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  title: '',
  subtitle: '',
  content: '',
  extra: '',
  coverMode: 'aspectFill',
  loadingText: '加载中...',
  emptyIcon: '📦',
  emptyText: '暂无数据',
  showHeader: true,
  showFooter: false,
  showArrow: false,
  clickable: false,
  shadow: 'hover',
  bordered: true,
  padding: '16px',
  margin: '0',
  customClass: ''
})

// Emits
const emit = defineEmits<{
  click: [event: any]
  coverLoad: [event: any]
  coverError: [event: any]
}>()

// 响应式数据
const isHovered = ref(false)

// 计算属性
const cardClass = computed(() => {
  return [
    {
      'card--clickable': props.clickable,
      'card--bordered': props.bordered,
      'card--shadow-hover': props.shadow === 'hover',
      'card--shadow-always': props.shadow === 'always',
      'card--hovered': isHovered.value && props.shadow === 'hover',
      'card--loading': props.loading,
      'card--empty': props.empty
    },
    props.customClass
  ]
})

const cardStyle = computed(() => {
  return {
    margin: props.margin,
    backgroundColor: props.backgroundColor || '#ffffff',
    borderRadius: props.borderRadius || '8px'
  }
})

const headerStyle = computed(() => {
  return {
    backgroundColor: props.headerBackgroundColor || 'transparent'
  }
})

const bodyStyle = computed(() => {
  return {
    padding: props.padding,
    backgroundColor: props.bodyBackgroundColor || 'transparent'
  }
})

const footerStyle = computed(() => {
  return {
    backgroundColor: props.footerBackgroundColor || 'transparent'
  }
})

// 方法
/**
 * 获取标签样式类
 */
const getTagClass = (tag: Tag) => {
  return [
    `tag--${tag.type || 'info'}`
  ]
}

/**
 * 获取标签样式
 */
const getTagStyle = (tag: Tag) => {
  const style: any = {}

  if (tag.color) {
    style.color = tag.color
  }

  if (tag.backgroundColor) {
    style.backgroundColor = tag.backgroundColor
  }

  return style
}

/**
 * 处理卡片点击
 */
const handleClick = (event: any) => {
  if (props.clickable) {
    emit('click', event)
  }
}

/**
 * 处理封面加载
 */
const handleCoverLoad = (event: any) => {
  emit('coverLoad', event)
}

/**
 * 处理封面加载错误
 */
const handleCoverError = (event: any) => {
  emit('coverError', event)
}
</script>

<style lang="scss" scoped>
.card {
  background: #ffffff;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;

  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 16px 0 16px;
    min-height: 48px;

    &-left {
      display: flex;
      align-items: center;
      flex: 1;
      min-width: 0;
    }

    &-icon {
      display: flex;
      align-items: center;
      margin-right: 12px;

      .icon {
        font-size: 18px;
        color: #1890ff;
      }
    }

    &-title {
      flex: 1;
      min-width: 0;

      .title-text {
        display: block;
        font-size: 16px;
        font-weight: 600;
        color: #333;
        line-height: 1.4;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .subtitle-text {
        display: block;
        font-size: 13px;
        color: #999;
        margin-top: 2px;
        line-height: 1.3;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }

    &-right {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    &-extra {
      .extra-text {
        font-size: 14px;
        color: #666;
      }
    }

    &-actions {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    &-arrow {
      display: flex;
      align-items: center;

      .arrow-icon {
        font-size: 18px;
        color: #ccc;
      }
    }
  }

  &__cover {
    position: relative;
    width: 100%;
    overflow: hidden;

    .cover-image {
      width: 100%;
      display: block;
    }

    .cover-content {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      background: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
      padding: 16px;
    }
  }

  &__body {
    flex: 1;
    position: relative;

    .content-text {
      font-size: 14px;
      color: #666;
      line-height: 1.6;
    }
  }

  &__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 16px 16px 16px;
    min-height: 48px;

    &-left {
      display: flex;
      align-items: center;
    }

    &-right {
      display: flex;
      align-items: center;
    }

    &-center {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
    }
  }

  &__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 16px 16px 16px;

    .tag {
      display: inline-flex;
      align-items: center;
      padding: 4px 8px;
      border-radius: 4px;
      font-size: 12px;
      line-height: 1;

      .tag-text {
        font-weight: 500;
      }

      &--primary {
        background: #e6f7ff;
        color: #1890ff;
      }

      &--success {
        background: #f6ffed;
        color: #52c41a;
      }

      &--warning {
        background: #fffbe6;
        color: #faad14;
      }

      &--danger {
        background: #fff2f0;
        color: #ff4d4f;
      }

      &--info {
        background: #f0f5ff;
        color: #722ed1;
      }
    }
  }

  &__loading {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.8);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 10;

    .loading-spinner {
      width: 24px;
      height: 24px;
      border: 2px solid #f3f3f3;
      border-top: 2px solid #1890ff;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      margin-bottom: 8px;
    }

    .loading-text {
      font-size: 14px;
      color: #999;
    }
  }

  &__empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    text-align: center;

    .empty-icon {
      font-size: 48px;
      margin-bottom: 16px;
      opacity: 0.5;
    }

    .empty-text {
      font-size: 14px;
      color: #999;
      margin-bottom: 8px;
    }

    .empty-description {
      font-size: 12px;
      color: #ccc;
      line-height: 1.5;
    }
  }

  // 状态样式
  &--clickable {
    cursor: pointer;

    &:active {
      transform: scale(0.98);
    }
  }

  &--bordered {
    border: 1px solid #f0f0f0;
  }

  &--shadow-hover {
    &:hover {
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
      transform: translateY(-2px);
    }
  }

  &--shadow-always {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  &--loading,
  &--empty {
    pointer-events: none;
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

// 响应式设计
@media (max-width: 480px) {
  .card {
    &__header {
      padding: 12px 12px 0 12px;

      &-icon {
        margin-right: 8px;

        .icon {
          font-size: 16px;
        }
      }

      &-title {
        .title-text {
          font-size: 15px;
        }

        .subtitle-text {
          font-size: 12px;
        }
      }
    }

    &__footer {
      padding: 0 12px 12px 12px;
    }

    &__tags {
      padding: 0 12px 12px 12px;
    }
  }
}
</style>